﻿using System;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Ejemplo
{
	[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
	public class FileSystemDataSource : HierarchicalDataSourceControl, IHierarchicalDataSource
	{
		//Set this property to a path to be able to view the files under this path, or, it it is not set, you'll view the conetnt of the root directory
		public String BaseDirectory { get { return mBaseDirectory; } set { mBaseDirectory = value; } }
		
		String mBaseDirectory = "";
		
		public FileSystemDataSource() : base() { }
		
		protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath)
		{
			HttpRequest currentRequest = HttpContext.Current.Request;
			if (viewPath != "")
				return new FileSystemDataSourceView(viewPath);
			if (mBaseDirectory != "")
				return new FileSystemDataSourceView(mBaseDirectory);
			return new FileSystemDataSourceView(currentRequest.MapPath(currentRequest.ApplicationPath));
		}
		
		protected override ControlCollection CreateControlCollection()
		{
			return new ControlCollection(this);
		}

	}
	
	public class FileSystemDataSourceView : HierarchicalDataSourceView
	{
		private string _viewPath;
		public FileSystemDataSourceView(string viewPath)
		{
			_viewPath = viewPath;
		}
		public override IHierarchicalEnumerable Select()
		{
			HttpRequest currentRequest = HttpContext.Current.Request;
			if (currentRequest.IsAuthenticated &&
			(currentRequest.UserHostAddress == "127.0.0.1" ||
			currentRequest.UserHostAddress == "::1"))
			{
				DirectoryInfo rootDirectory = new DirectoryInfo(_viewPath);
				FileSystemHierarchicalEnumerable fshe = new FileSystemHierarchicalEnumerable();
				foreach (FileSystemInfo fsi in rootDirectory.GetFileSystemInfos())
				{
					fshe.Add(new FileSystemHierarchyData(fsi));
				}
				return fshe;
			}
			else
			{
				throw new NotSupportedException("The FileSystemDataSource only " + "presents data in an authenticated, localhost context.");
			}
		}
	}
	// A collection of FileSystemHierarchyData objects
	
	public class FileSystemHierarchicalEnumerable : ArrayList, IHierarchicalEnumerable
	{
		public FileSystemHierarchicalEnumerable()
			: base()
		{
		}
		public IHierarchyData GetHierarchyData(object enumeratedItem)
		{
			return enumeratedItem as IHierarchyData;
		}
	}
	
	public class FileSystemHierarchyData : IHierarchyData
	{
		public FileSystemHierarchyData(FileSystemInfo obj)
		{
			fileSystemObject = obj;
		}
		private FileSystemInfo fileSystemObject = null;
		
		public override string ToString()
		{
			return fileSystemObject.Name;
		}
		// IHierarchyData implementation.
		
		public bool HasChildren
		{
			get
			{
				if (fileSystemObject is FileInfo)
					return false;
				DirectoryInfo dir = fileSystemObject as DirectoryInfo;
				return dir.GetFileSystemInfos().Length != 0;
			}
		}
		
		public string Path
		{
			get
			{
				return fileSystemObject.FullName;
			}
		}
		
		public object Item
		{
			get
			{
				return fileSystemObject;
			}
		}
		
		public string Type
		{
			get
			{
				return "FileSystemData";
			}
		}
		
		public IHierarchicalEnumerable GetChildren()
		{
			FileSystemHierarchicalEnumerable children =
					 new FileSystemHierarchicalEnumerable();

			if (typeof(DirectoryInfo) == fileSystemObject.GetType())
			{
				DirectoryInfo temp = (DirectoryInfo)fileSystemObject;
				foreach (FileSystemInfo fsi in temp.GetFileSystemInfos())
				{
					children.Add(new FileSystemHierarchyData(fsi));
				}
			}
			return children;

		}
		
		public IHierarchyData GetParent()
		{
			FileSystemHierarchicalEnumerable parentContainer =
					 new FileSystemHierarchicalEnumerable();

			if (typeof(DirectoryInfo) == fileSystemObject.GetType())
			{
				DirectoryInfo temp = (DirectoryInfo)fileSystemObject;
				return new FileSystemHierarchyData(temp.Parent);
			}
			else if (typeof(FileInfo) == fileSystemObject.GetType())
			{
				FileInfo temp = (FileInfo)fileSystemObject;
				return new FileSystemHierarchyData(temp.Directory);
			}
			// If FileSystemObj is any other kind of FileSystemInfo, ignore it.
			return null;

		}
	}
}
